/*
 * lock.h
 */

#ifndef LOCK_H_
#define LOCK_H_

#ifndef LIBDLM_H_
# include "libdlm.h"
#endif
#include <sys/types.h>

typedef __int8_t lock_restriction_t;
typedef __int8_t lock_mask_t;

#include <sys/types.h>
#include <sys/stat.h>

#define RESOURCES_TAB_MAX_SIZE 128

void lock_init(void);

/* checking functions */
/*
 *	lock_ck_process() sprawdza czy proces znajduje się w liście procesów
 *  wskazywanych przez proc_root. Jeżeli zostanie znalezione jest zwracany,
 *  jeżeli nie - zwracany NULL.
 */
struct process* lock_ck_process(pid_t pid);
/*
 *	lock_ck_resource_stat() sprawdza czy zasob opisany przez st znajduje się
 *  w liście zasobów wskazywanych przez res_root. Jeżeli zostanie znalezione
 *  jest zwracany, jeżeli nie - zwracany NULL.
 */
struct resource* lock_ck_resource_stat(struct stat* st);
/*
 *	lock_ck_resource() sprawdza czy zasob o id == resid st znajduje się
 *  w liście zasobów wskazywanych przez res_root. Jeżeli zostanie znalezione
 *  jest zwracany, jeżeli nie - zwracany NULL.
 */
struct resource* lock_ck_resource(resource_id_t resid);
struct lock* lock_ck_lock(struct resource *res, struct process *proc);
/* add functions */
/*
 *  lock_add_process dodaje proces o podanym pid i fd do listy procesów.
 *  Zwraca wskaźnik na utworzony proces.
 */
struct process* lock_add_process(pid_t pid);
struct resource* lock_add_resource(struct stat* st);
struct lock* lock_add_lock(struct process *proc, struct resource *res, struct lock *lock);
struct lock* lock_trylock(struct process *proc, struct resource *res, lock_type_t type);
int lock_add_waiting_lock(struct lock *lock, struct lock *conflict);

/* link functions */
void lock_link_proc_res(struct process *proc, struct resource *res);
//void lock_unlink_proc_res(struct process *proc, struct resource *res);
int lock_rm_process(struct process *proc);
struct lock* lock_rm_lock(struct lock *lock, struct resource *res);
//int lock_rm_resource(struct resource *res);
struct lock* lock_get_waiting_lock();

//void lock_link_res_lock(struct resource *res, struct lock *lock);
//void lock_link_waiting_lock(struct lock *lock);
/* unlink functions */
//void lock_unlink_proc_res(struct process *proc, struct resource *res);
//void lock_unlink_res_lock(struct resource *res, struct lock *lock);
//void lock_unlink_waiting_lock(struct lock *lock);

/* process abstraction */
struct process {
	pid_t pid;					 	// processe's pid
	int fd;							// file descriptor
	int resource_links;				// resources registered by process
	struct resource **resources;	// registered resources by the process
    struct process *next;           // NULL if next process doesn't exist
    struct process *prev;           // NULL if previous process doesn't exist
};
/* resource abstraction */
struct resource {
	resource_id_t id;			// internal id
	ino_t st_ino;				// external id
	dev_t st_dev;				// .
	dev_t st_rdev;				// .
	int links;					// how many processes registered this resource
	struct lock *locks;			// locks on resource
	struct resource *next;		// resources are in a list
	struct resource *prev;		// .
};
/* lock abstraction */
struct lock {
	struct process *proc;		// process that locked resource
	resource_id_t resource;		// resource to be locked
	lock_restriction_t type;	// lock restrictions
	time_t expire;				// for locks with timeout
	struct lock *next;
	struct lock *prev;
	struct lock *conflict_next;		// locks with conflict
	struct lock *conflict_prev;
};
#endif /* LOCK_H_ */
